package com.quickcancellation.crm.utils;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

public class ExcelExporter {
  public static void exportToExcelByMap(List<Map<String, Object>> data, String []columnNames,String fileName) throws IOException {
    // 创建工作簿对象
    Workbook workbook = new XSSFWorkbook();

    // 创建工作表对象
    Sheet sheet = workbook.createSheet("Sheet1");

    // 创建表头行
    Row headerRow = sheet.createRow(0);

    // 遍历第一条数据的键值，创建表头单元格
    int colIndex = 0;
    for (int i = 0; i < columnNames.length; i++) {
      Cell cell = headerRow.createCell(i, CellType.STRING);
      cell.setCellValue(columnNames[i]);
    }

    // 遍历数据列表，创建数据行
    int rowIndex = 1;
    for (Map<String, Object> row : data) {
      Row dataRow = sheet.createRow(rowIndex++);
      colIndex = 0;
      for (Object value : row.values()) {
        Cell cell = dataRow.createCell(colIndex++);
        if (value instanceof String) {
          cell.setCellValue((String) value);
        } else if (value instanceof Integer) {
          cell.setCellValue((Integer) value);
        } else if (value instanceof Double) {
          cell.setCellValue((Double) value);
        }
      }
    }

    // 将工作簿写入输出流
    try (FileOutputStream outputStream = new FileOutputStream(fileName)) {
      workbook.write(outputStream);
    }
  }

  /**
   * 分批导出
   * @param data
   * @param columnNames
   * @return
   * @throws Exception
   */
  public static Workbook export2ExcelToThread(List<Map<String, Object>> data, String[] columnNames) throws Exception {
    int pageSize = 5000;
    int pageCount = (data.size() - 1) / pageSize + 1;

    ExecutorService executor = Executors.newFixedThreadPool(pageCount);
    List<Future<Workbook>> futures = new ArrayList<>();
    for (int i = 0; i < pageCount; i++) {
      int fromIndex = i * pageSize;
      int toIndex = Math.min((i + 1) * pageSize, data.size());
      List<Map<String, Object>> pageData = data.subList(fromIndex, toIndex);

      futures.add(executor.submit(() -> {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Sheet1");
        Row headerRow = sheet.createRow(0);
        for (int j = 0; j < columnNames.length; j++) {
          Cell cell = headerRow.createCell(j, CellType.STRING);
          cell.setCellValue(columnNames[j]);
        }

        int rowIndex = 1;
        for (Map<String, Object> row : pageData) {
          Row dataRow = sheet.createRow(rowIndex++);
          int colIndex = 0;
          for (Object value : row.values()) {
            Cell cell = dataRow.createCell(colIndex++);
            if (value instanceof String) {
              cell.setCellValue((String) value);
            } else if (value instanceof Integer) {
              cell.setCellValue((Integer) value);
            } else if (value instanceof Double) {
              cell.setCellValue((Double) value);
            }
          }
        }

        return workbook;
      }));
    }

    List<Workbook> workbooks = new ArrayList<>();
    for (Future<Workbook> future : futures) {
      workbooks.add(future.get());
    }

    executor.shutdown();

    Workbook resultWorkbook = new XSSFWorkbook();
    Sheet resultSheet = resultWorkbook.createSheet("Sheet1");
    Row resultHeaderRow = resultSheet.createRow(0);
    for (int i = 0; i < columnNames.length; i++) {
      Cell cell = resultHeaderRow.createCell(i, CellType.STRING);
      cell.setCellValue(columnNames[i]);
    }

    return resultWorkbook;
  }


  public static Workbook export2ExcelThread(List<Map<String, Object>> data, String[] columnNames) throws IOException, InterruptedException, ExecutionException {
    // 创建工作簿对象
    Workbook workbook = new XSSFWorkbook();

    // 创建工作表对象
    Sheet sheet = workbook.createSheet("Sheet1");

    // 创建表头行
    Row headerRow = sheet.createRow(0);

    // 遍历第一条数据的键值，创建表头单元格
    AtomicInteger colIndex = new AtomicInteger();
    for (int i = 0; i < columnNames.length; i++) {
      Cell cell = headerRow.createCell(i, CellType.STRING);
      cell.setCellValue(columnNames[i]);
    }

    // 创建线程池，最大线程数为CPU核心数
    ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    // 创建Future对象列表
    List<Future<?>> futures = new ArrayList<>();

    // 遍历数据列表，创建数据行
    int rowIndex = 1;
    for (Map<String, Object> row : data) {
      final int index = rowIndex;
      futures.add(executor.submit(() -> {
        Row dataRow = sheet.createRow(index);
        colIndex.set(0);
        for (Object value : row.values()) {
          Cell cell = dataRow.createCell(colIndex.getAndIncrement());
          if (value instanceof String) {
            cell.setCellValue((String) value);
          } else if (value instanceof Integer) {
            cell.setCellValue((Integer) value);
          } else if (value instanceof Double) {
            cell.setCellValue((Double) value);
          }
        }
      }));
      rowIndex++;
    }

    // 等待所有任务执行完毕
    for (Future<?> future : futures) {
      future.get();
    }

    // 关闭线程池
    executor.shutdown();

    return workbook;
  }


  public static Workbook export2Excel(List<Map<String, Object>> data, String []columnNames) throws IOException {
    // 创建工作簿对象
    Workbook workbook = new XSSFWorkbook();

    // 创建工作表对象
    Sheet sheet = workbook.createSheet("Sheet1");

    // 创建表头行
    Row headerRow = sheet.createRow(0);

    // 遍历第一条数据的键值，创建表头单元格
    int colIndex = 0;
    for (int i = 0; i < columnNames.length; i++) {
      Cell cell = headerRow.createCell(i, CellType.STRING);
      cell.setCellValue(columnNames[i]);
    }

    // 遍历数据列表，创建数据行
    int rowIndex = 1;
    for (Map<String, Object> row : data) {
      Row dataRow = sheet.createRow(rowIndex++);
      colIndex = 0;
      for (Object value : row.values()) {
        Cell cell = dataRow.createCell(colIndex++);
        if (value instanceof String) {
          cell.setCellValue((String) value);
        } else if (value instanceof Integer) {
          cell.setCellValue((Integer) value);
        } else if (value instanceof Double) {
          cell.setCellValue((Double) value);
        }
      }
    }

   return workbook;
  }


  /**
   * 导出待excel
   * @param data
   * @param filename
   * @param <T>
   * @throws IOException
   */
  public static <T> void exportToExcel(List<T> data,String []columnNames ,String filename) throws IOException {
    // 创建一个工作簿
    XSSFWorkbook workbook = new XSSFWorkbook();

    // 创建一个工作表
    Sheet sheet = workbook.createSheet("Sheet1");

    // 添加列名
    Row headerRow = sheet.createRow(0);
    Field[] fields = data.get(0).getClass().getDeclaredFields();  // 获取实体类的所有属性
//    for (int i = 0; i < fields.length; i++) {
//      headerRow.createCell(i, CellType.STRING).setCellValue(fields[i].getName());
//    }

    for (int i = 0; i < columnNames.length; i++) {
      Cell cell = headerRow.createCell(i, CellType.STRING);
      cell.setCellValue(columnNames[i]);
    }

    // 添加数据行
    int rowIndex = 1;
    for (T entity : data) {
      Row dataRow = sheet.createRow(rowIndex++);
      int cellIndex = 0;
      for (Field field : fields) {
        try {
          field.setAccessible(true);
          Object value = field.get(entity);
          if (value != null) {
            if (value instanceof Number) {
              dataRow.createCell(cellIndex++, CellType.NUMERIC).setCellValue(((Number) value).doubleValue());
            } else {
              dataRow.createCell(cellIndex++, CellType.STRING).setCellValue(value.toString());
            }
          } else {
            dataRow.createCell(cellIndex++, CellType.BLANK);
          }
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
    }
    // 导出 Excel 文件
    FileOutputStream outputStream = new FileOutputStream(filename);
    workbook.write(outputStream);
    workbook.close();
    outputStream.close();

    System.out.println("Excel 文件导出成功！");
  }


  // 导出实体类列表到 Excel 文件
  // 导出列表到 Excel 文件
  public static <T> void export(List<T> data, String[] columnNames, String filename) throws IOException, NoSuchFieldException, IllegalAccessException {
    // 创建一个工作簿和一个工作表
    XSSFWorkbook workbook = new XSSFWorkbook();
    Sheet sheet = workbook.createSheet("Sheet1");

    // 添加列头
    Row headerRow = sheet.createRow(0);
    for (int i = 0; i < columnNames.length; i++) {
      Cell cell = headerRow.createCell(i, CellType.STRING);
      cell.setCellValue(columnNames[i]);
    }

    // 添加数据行
    int rowIndex = 1;
    for (T entity : data) {
      Row dataRow = sheet.createRow(rowIndex++);
      for (int i = 0; i < columnNames.length; i++) {
//        Object value = null;
        // TODO: 根据属性名获取实体类的属性值
        Object value = null;
//        Object value = null;
        String propertyName = columnNames[i];
        Field field = entity.getClass().getDeclaredField(propertyName);
        field.setAccessible(true);
        value = field.get(entity);
        Cell cell = dataRow.createCell(i);
        setCellValue(cell, value);  // 设置单元格的值，参考上一条回答中的示例代码
      }
    }

    // 导出 Excel 文件
    FileOutputStream outputStream = new FileOutputStream(filename);
    workbook.write(outputStream);
    workbook.close();
    outputStream.close();

    System.out.println("Excel 文件导出成功！");
  }


  public static void setCellValue(Cell cell, Object value) {
    if (value == null) {
      cell.setCellType(CellType.BLANK);
    } else if (value instanceof String) {
      cell.setCellValue((String) value);
    } else if (value instanceof Number) {
      cell.setCellValue(((Number) value).doubleValue());
    } else if (value instanceof Boolean) {
      cell.setCellValue((Boolean) value);
    } else if (value instanceof Date) {
      cell.setCellValue((Date) value);
    } else {
      cell.setCellValue(value.toString());
    }
  }



  // 导出实体类列表到 Excel 文件
  public static <T> void export(List<T> data, String filename) throws IOException {
    // 创建一个工作簿
    XSSFWorkbook workbook = new XSSFWorkbook();

    // 创建一个工作表
    Sheet sheet = workbook.createSheet("Sheet1");

    // 添加列名
    Row headerRow = sheet.createRow(0);
    Field[] fields = data.get(0).getClass().getDeclaredFields();  // 获取实体类的所有属性
    for (int i = 0; i < fields.length; i++) {
      headerRow.createCell(i, CellType.STRING).setCellValue(fields[i].getName());
    }

    // 添加数据行
    int rowIndex = 1;
    for (T entity : data) {
      Row dataRow = sheet.createRow(rowIndex++);
      int cellIndex = 0;
      for (Field field : fields) {
        try {
          field.setAccessible(true);
          Object value = field.get(entity);
          if (value != null) {
            if (value instanceof Number) {
              dataRow.createCell(cellIndex++, CellType.NUMERIC).setCellValue(((Number) value).doubleValue());
            } else {
              dataRow.createCell(cellIndex++, CellType.STRING).setCellValue(value.toString());
            }
          } else {
            dataRow.createCell(cellIndex++, CellType.BLANK);
          }
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
    }

    // 导出 Excel 文件
    FileOutputStream outputStream = new FileOutputStream(filename);
    workbook.write(outputStream);
    workbook.close();
    outputStream.close();

    System.out.println("Excel 文件导出成功！");
  }

  public static <T> void export2(List<T> data, String[] columnNames, String filename) throws IOException {
    // 创建一个工作簿和一个工作表
    XSSFWorkbook workbook = new XSSFWorkbook();
    Sheet sheet = workbook.createSheet("Sheet1");

    // 添加列头
    Row headerRow = sheet.createRow(0);
    for (int i = 0; i < columnNames.length; i++) {
      Cell cell = headerRow.createCell(i, CellType.STRING);
      cell.setCellValue(columnNames[i]);
    }

    // 添加数据行
    int rowIndex = 1;
    for (T entity : data) {
      Row dataRow = sheet.createRow(rowIndex++);
      for (int i = 0; i < columnNames.length; i++) {
        Object value = data.get(i);
        Cell cell = dataRow.createCell(i);
        setCellValue(cell, value);  // 设置单元格的值，参考前面的示例代码
      }
    }

    // 导出 Excel 文件
    FileOutputStream outputStream = new FileOutputStream(filename);
    workbook.write(outputStream);
    workbook.close();
    outputStream.close();

    System.out.println("Excel 文件导出成功！");
  }


}
